package pl.enigmatic.validation.fields;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import pl.enigmatic.validation.SetsValue;


@SuppressWarnings("rawtypes")
public abstract class BasicEditorUtil<T, F extends Enum<F> & Field<T, Object>, Input extends SetsValue> implements HasFieldWidgets<F, Input>,
		SetsValue<T> {

	private final Map<F, Input> fields = new HashMap<F, Input>();
	private T value = null;

	public <AF extends Input> AF wrap(final F field, final AF editor) {
		fields.put(field, editor);
		return editor;
	}

	@Override
	public boolean contains(final F field) {
		return fields.containsKey(field);
	}

	@Override
	public Input getEditor(final F field) {
		return fields.get(field);
	}

	protected abstract T createValue();

	@Override
	public T getValue() {
		if (value == null) {
			value = createValue();
		}
		for (final Entry<F, Input> e : fields.entrySet()) {
			e.getKey().set(value, e.getValue().getValue());
		}
		return value;
	}

	@SuppressWarnings({ "unchecked" })
	@Override
	public T setValue(final T val) {
		value = val;
		if (value != null) {
			for (final Entry<F, Input> e : fields.entrySet()) {
				e.getValue().setValue(e.getKey().project(value));
			}
		} else {
			for (final Input e : fields.values()) {
				e.setValue(null);
			}
		}
		return value;
	}

}
